import 'package:dio/dio.dart';
import 'package:logger/logger.dart';
import 'package:lovify/core/constants/config.dart';

class ApiException implements Exception {
  final String message;
  final int? statusCode;

  ApiException(this.message, {this.statusCode});

  @override
  String toString() => 'ApiException: $message (Status Code: $statusCode)';
}

class ApiClient {
  final Dio _dio;

  final Logger logger = Logger(printer: PrettyPrinter());
  ApiClient()
      : _dio = Dio(BaseOptions(
          baseUrl: baseApiUrl,
          headers: {
            'Content-Type': 'application/json',
          },
        ));

  Future<dynamic> _request<T>(
    String method,
    String endpoint, {
    dynamic data,
    Map<String, String>? params,
    Map<String, String>? headers,
    Options? options,
    Function(int, int)? onProgress,
  }) async {
    try {
      final response = await _dio.request(
        endpoint,
        data: data,
        queryParameters: params,
        options: options ?? Options(headers: headers, method: method),
        onReceiveProgress: onProgress,
      );
      return response.data;
    } catch (e) {
      throw ApiException('$method 请求失败: $e');
    }
  }

  Future<dynamic> get(
    String endpoint, {
    Map<String, String>? params,
    Map<String, String>? headers,
  }) {
    return _request('GET', endpoint, params: params, headers: headers);
  }

  Future<dynamic> post(
    String endpoint, {
    dynamic body,
    Map<String, String>? headers,
    Options? options,
  }) {
    return _request('POST', endpoint,
        data: body, headers: headers, options: options);
  }

  Future<dynamic> put(
    String endpoint, {
    dynamic body,
    Map<String, String>? headers,
    Options? options,
  }) {
    return _request('PUT', endpoint,
        data: body, headers: headers, options: options);
  }

  Future<dynamic> delete(
    String endpoint, {
    dynamic body,
    Map<String, String>? headers,
    Options? options,
  }) {
    return _request('DELETE', endpoint,
        data: body, headers: headers, options: options);
  }

  Future<dynamic> file(
    String endpoint, {
    required String filePath,
    Function(int, int)? onProgress,
    Map<String, String>? headers,
    Map<String, String>? params,
  }) async {
    final formData = FormData.fromMap({
      'file': await MultipartFile.fromFile(filePath,
          filename: filePath.split('/').last),
    });

    final response = await _dio.post(
      endpoint,
      data: formData,
      queryParameters: params,
      options: Options(headers: headers),
      onSendProgress: onProgress,
    );

logger.i(response);
    return response.data;
  }

  Dio get dio => _dio;
}
